package com.guoxw.headerdemo.behaviors;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

import androidx.annotation.NonNull;
import androidx.coordinatorlayout.widget.CoordinatorLayout;

import com.google.android.material.appbar.AppBarLayout;

public class MyBehavior extends AppBarLayout.Behavior {

    private final static String TAG = MyBehavior.class.getName().toString();

    /**
     * 表示无效的触摸点
     **/
    private static final int INVALID_POINTER = -1;
    /**
     * 是否正在被拖拽
     **/
    private boolean isBeingDragged;
    /**
     * 当前活动的触摸点的 id
     **/
    private int activePointerId = INVALID_POINTER;
    /**
     * 上一次触摸事件的Y坐标
     **/
    private int lastMotionY;
    /**
     * 上一次触摸事件的X坐标
     **/
    private int lastMotionX;
    /**
     * 触摸的最小滑动距离
     **/
    private final int touchSlop;
    /**
     * 当前触摸事件
     **/
    private MotionEvent currentMotionEvent;
    /**
     * 是否需要将事件分发给下层 View
     **/
    private boolean needDispatchDown;
    /**
     * 与 AppBarLayout 关联的可滚动 View
     **/
    private View scrollViewBehaviorView;


    public MyBehavior(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        Log.i(TAG,"=MyBehavior 111 ===touchSlop="+touchSlop);
    }

    /**
     * 这段代码的作用是判断用户是否正在拖拽 AppBarLayout。当用户按下触摸点时，记录下触摸点的坐标和触摸点的 ID；
     * 当用户移动触摸点时，计算触摸点移动的距离，并判断是否大于 touchSlop，
     * 如果是则认为正在拖拽；当用户取消或抬起触摸点时，清除拖拽状态并将事件设置为 ACTION_CANCEL
     * 。如果有关联的子 View（如 NestedScrollView），则将事件发送给子 View 处理。最后返回是否正在拖拽的状态。
     **/
    @Override
    public boolean onInterceptTouchEvent(@NonNull CoordinatorLayout parent, @NonNull AppBarLayout child, @NonNull MotionEvent ev) {

//        if (ev.getActionMasked() == MotionEvent.ACTION_MOVE && isBeingDragged) {
//            return true;
//        }


        Log.i(TAG,"=onInterceptTouchEvent======"+ev.getActionMasked()+"=====x="+ev.getX()+"=====y="+ev.getY());
        switch (ev.getActionMasked()) {
            case MotionEvent.ACTION_DOWN: {
                isBeingDragged = false;
                needDispatchDown = true;
                //获取触摸点的坐标
                final  int x = (int) ev.getX();
                final   int y = (int) ev.getY();

                //检查触摸点是否在appbarlayout中
                if (parent.isPointInChildBounds(child, x, y)) {
                    Log.i(TAG, "=onInterceptTouchEvent in child view======");

                    //如果在，则记录下坐标点和触摸点的id
                    lastMotionX = x;
                    lastMotionY = y;
                    activePointerId = ev.getPointerId(0);
                    //回收之前的滑动MotionEvent
                    if (currentMotionEvent != null) {
                        currentMotionEvent.recycle();
                    }
                    //复制当前的滑动 MotionEvent
                    try {
                        Log.i(TAG, "=onInterceptTouchEvent in child view=2=====");

                        currentMotionEvent = MotionEvent.obtain(ev);
                        Log.i(TAG, "=onInterceptTouchEvent in child view=3=====");

                    } catch (Exception e) {
//                        e.printStackTrace();
                        Log.e(TAG, e.getMessage());
                    }

                }

                break;
            }
            case MotionEvent.ACTION_MOVE: {
                Log.i(TAG, "=onInterceptTouchEvent activePointerId=" + activePointerId);
                final int mactivePointerId = activePointerId;
                //检查是否正在拖拽
                if (mactivePointerId == INVALID_POINTER) {
                    break;
                }

                //获取触摸点的坐标
                final   int pointerIndex = ev.findPointerIndex(mactivePointerId);

                Log.i(TAG, "=onInterceptTouchEvent pointerIndex=" + pointerIndex);

                if (pointerIndex == -1) {
                    break;
                }

                final     int moveX = (int) ev.getX(pointerIndex);
                final    int moveY = (int) ev.getY(pointerIndex);

                //计算触摸点移动距离；
                final    int xDifff = Math.abs(moveX - lastMotionX);
                final    int yDifff = Math.abs(moveY - lastMotionY);

                Log.i(TAG, "=yDifff=" + yDifff + "===touchSlop=" + touchSlop + "===xDifff=" + xDifff);

                if (yDifff > touchSlop && yDifff > xDifff) {

                    Log.i(TAG, "==============isBeingDragged set true=======");


                    isBeingDragged = true;
                }

                break;
            }
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL: {

                //取消拖拽状态
                isBeingDragged = false;
                needDispatchDown = true;
                activePointerId = INVALID_POINTER;
                //清除拖拽事件
//                currentMotionEvent = null;
//                //
//                ev.setAction(MotionEvent.ACTION_CANCEL);

                break;
            }
            default:
                break;
        }
//        boolean b = super.onInterceptTouchEvent(parent, child, ev);
//        Log.i(TAG,"==onInterceptTouchEvent===========b="+b);
//        return b;
        Log.i(TAG,"==onInterceptTouchEvent===========isBeingDragged="+isBeingDragged);

//        if(isBeingDragged == false){
//            super.onInterceptTouchEvent(parent, child, ev);
//        }

        return isBeingDragged;
    }

    @Override
    public boolean onTouchEvent(@NonNull CoordinatorLayout parent, @NonNull AppBarLayout child, @NonNull MotionEvent ev) {

        Log.i(TAG,"=onTouchEvent======"+ev.getActionMasked()+"=====x="+ev.getX()+"=====y="+ev.getY());
        switch (ev.getActionMasked()){
            case MotionEvent.ACTION_MOVE:

                Log.i(TAG,"=onTouchEvent  MotionEvent.ACTION_MOVE =================isBeingDragged="+isBeingDragged);

                //正在被拖拽
                if(isBeingDragged){
                    //正在拖拽
                    final        int offset = child.getHeight() - child.getBottom();
                    //需要分发
                    if (needDispatchDown == true){
                        needDispatchDown = false;
                        MotionEvent downEvent = MotionEvent.obtain(currentMotionEvent);
                        downEvent.offsetLocation(0,offset);
                        if (scrollViewBehaviorView != null){

                            boolean b = scrollViewBehaviorView.dispatchTouchEvent(downEvent);

                            Log.i(TAG,"==onTouchEvent ACTION_MOVE 1 ======= b ="+b);
                        }
                    }

                    MotionEvent motionEvent = MotionEvent.obtain(ev);
                    motionEvent.offsetLocation(0,offset);
                    if (scrollViewBehaviorView!=null){
                        boolean b = scrollViewBehaviorView.dispatchTouchEvent(motionEvent);

                        Log.i(TAG,"==onTouchEvent ACTION_MOVE 2======= b ="+b);
                        return true;
                    }
                }

                break;
            case MotionEvent.ACTION_UP:
                //正在被拖拽
                if(isBeingDragged){
                    ev.offsetLocation(0,child.getHeight()-child.getBottom());
                    if (scrollViewBehaviorView!=null){
                        boolean b = scrollViewBehaviorView.dispatchTouchEvent(ev);
                        Log.i(TAG,"==onTouchEvent ACTION_UP======= b ="+b);
                        return true;
                    }
                }

                break;
//                case MotionEvent.ACTION_DOWN:
//
//
//                    return true;
////                    break;

        }

        boolean b = super.onTouchEvent(parent, child, ev);
        Log.i(TAG,"==onTouchEvent===========b="+b);
        // 如果事件没有被正确处理，则返回false，将事件交给父类处理
        return b;
    }


    @Override
    public boolean onLayoutChild(@NonNull CoordinatorLayout parent, @NonNull AppBarLayout abl, int layoutDirection) {
        boolean b = super.onLayoutChild(parent, abl, layoutDirection);
        for (int i = 0,c = parent.getChildCount(); i < c; i++) {

            View sibling = parent.getChildAt(i);

            Log.i(TAG,"=onLayoutChild  i =================="+i +"========c="+c);


           final CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) sibling.getLayoutParams()).getBehavior();
            if (behavior instanceof AppBarLayout.ScrollingViewBehavior){

                Log.i(TAG,"=onLayoutChild set scrollViewBehaviorView==================");

                scrollViewBehaviorView = sibling;
            }

        }

        return b;
    }
}
